/**
 * 封装加密类
 * */

import cryptoJs from "crypto-js";
import { v4 as uuidv4 } from "uuid";
import dayjs from "dayjs";

export class CryptoTool {
  // crypto拥有crypto的所有属性方法
  static cryptoJs: typeof cryptoJs = cryptoJs;

  constructor() {
  }

  /**
   * 获取uuid
   * @param {boolean} strike - 是否显示中划线
   * @return {string}
   * */
  static getUuid(strike: boolean = false): string {
    let uuid = uuidv4();
    if (!strike) uuid = uuid.replace(/-/g, "");
    return uuid;
  }

  /**
   * 获取日期编号
   * @param {string} format - 时间格式化模板
   * @return {string}
   * */
  static getDate(format: string = "YYYYMMDDHHmmss"): string {
    return dayjs().format(format);
  }

  /**
   * DES解密
   * @param {string} data - 加密串
   * @param {string} key - 密钥
   * @return {string}
   * */
  static desDecrypt(data: string, key: string): string {
    return CryptoTool.cryptoJs.DES.decrypt(data, key).toString(CryptoTool.cryptoJs.enc.Utf8);
  }

  /**
   * DES加密
   * @param {string | object} data - 被加密内容
   * @param {string} key - 密钥
   * @return {string}
   * */
  static desEncrypt(data: string | object, key: string): string {
    if (typeof data === "object") data = JSON.stringify(data);
    return CryptoTool.cryptoJs.DES.encrypt(data, key).toString();
  }

  /**
   * @description: 随机密码
   * @param {number} len 密码位数
   * @param {RandomPassMode} mode 密码难度
   * @return {string}
   */
  static randomPass(len = 8, mode: RandomPassMode = "high"): string {
    const lowerCaseArr = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
    const blockLetterArr = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
    const numberArr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
    const specialArr = ["!", "@", "-", "_", "=", "<", ">", "#", "*", "%", "+", "&", "^", "$"];
    const passArr = [];
    let password = "";

    //指定参数随机获取一个字符
    const specifyRandom = function(...arr: any[]) {
      let str = "";
      arr.forEach(item => {
        str += item[Math.floor(Math.random() * item.length)];
      });
      return str;
    };

    switch (mode) {
      case "high":
        //安全最高的
        password += specifyRandom(lowerCaseArr, blockLetterArr, numberArr, specialArr);
        passArr.push(...lowerCaseArr, ...blockLetterArr, ...numberArr, ...specialArr);
        break;
      case "medium":
        //中等的
        password += specifyRandom(lowerCaseArr, blockLetterArr, numberArr);
        passArr.push(...lowerCaseArr, ...blockLetterArr, ...numberArr);
        break;
      //低等的
      case "low":
        password += specifyRandom(lowerCaseArr, numberArr);
        passArr.push(...lowerCaseArr, ...numberArr);
        break;
      default:
        password += specifyRandom(lowerCaseArr, numberArr);
        passArr.push(...lowerCaseArr, ...numberArr);
    }

    const forLen = len - password.length;
    for (let i = 0; i < forLen; i++) {
      password += specifyRandom(passArr);
    }

    return password;
  }
}

// 随机密码强度：high(大小写数字特殊字符)、medium(大小写数字)、low(小写数字)
export declare type RandomPassMode = "high" | "medium" | "low";
